<?php
class Model extends DB
{
    /**
     * @var array
     *
     * 'required',
     * 'email',
     * 'numeric',
     * 'maxLength',
     * 'minLength',
     */
    public $rules = array();
    public $attributes = array();
    public $tableName = '';


    public function beforeSave()
    {
        return true;
    }

    public function afterSave()
    {
        return true;
    }

    public function insert()
    {
        $this->beforeSave();
        if ($this->execute("INSERT INTO {$this->tableName}
            (" . implode(', ', array_keys($this->attributes)) . ")
            VALUES (:" . implode(', :', array_keys($this->attributes)) . ")",
            $this->getParams())){
            $this->afterSave();
            return true;
        }
        return false;
    }

    public function update($id)
    {
        $setValues = '';
        $index = 1;
        foreach ($this->attributes as $key => $value) {
            $setValues .= "{$key}=:{$key}";
            $setValues .= ($index < count($this->attributes)) ? ',' : '';
            $index++;
        }
        return $this->execute("UPDATE {$this->tableName} SET " . $setValues . " WHERE id=" . (int)$id, $this->getParams());
    }

    public function getParams()
    {
        $params = array();
        if ($this->validate()) {
            foreach ($this->attributes as $key => $value) {
                $params[":{$key}"] = $value;
            }
            return $params;
        } else throw new Exception('Not Valid');
    }

    public function validate()
    {
        if (!empty($this->attributes)) {
            foreach ($this->attributes as $key => $value) {
                $result = $this->checkValue($value, $this->rules[$key]);
                if ($result[0])
                    throw new Exception($result[1]);
            }
            return true;
        } else return false;
    }

    public function checkValue($value = null, $rule)
    {
        $hasError = false;
        $errorString = '';
        if (is_array($rule)) {
            foreach ($rule as $checkRule => $item) {
                $checkValue = (isset($item)) ? $item : null;
                switch ($checkRule) {
                    case 'required':
                        $hasError = !isset($value);
                        $errorString = 'Пустое поле: ';
                        break;
                    case 'email':
                        $hasError = filter_var($value, FILTER_VALIDATE_EMAIL);
                        $errorString = 'Некорректный E-mail: ';
                        break;
                    case 'numeric':
                        $hasError = filter_var($value, FILTER_VALIDATE_INT);
                        $errorString = 'Значение должно быть целым числом: ';
                        break;
                    case 'maxLength':
                        $hasError = (strlen($value) > (int)$checkValue);
                        $errorString = 'Значение должно быть целым числом: ';
                        break;
                    default:
                        $hasError = true;
                        $errorString = 'Не указано правило валидации';
                        break;
                }
            }
        } else {
            $hasError = true;
            $errorString = 'Неверно указано правило валидации, ожидается массив';
        }
        return array($hasError, $errorString);
    }

}